#include "iplineedit.h"
#include <QHBoxLayout>
#include<QLabel>
#include <QRegExp>
#include <QRegExpValidator>
#include<QEvent>
#include<QKeyEvent>
IPLineEdit::IPLineEdit(QWidget *parent)
    :QLineEdit(parent)
{
    QHBoxLayout *layout=new QHBoxLayout(this);
    layout->setContentsMargins(5,5,5,5); // 设置布局的边距为 1 像素

    // 定义正则表达式，匹配有效的IP地址段 (0-255)
    QRegExp regExp("(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})");

    QLabel *labelDot[3];// 用于存储分隔符 "." 的标签控件
    for(int i=0;i<LINEEDIT_SIZE;i++)// 循环初始化每段IP地址的输入框
    {
        m_LineEdit[i]=new QLineEdit(this);// 创建每段IP地址的 QLineEdit 控件

        m_LineEdit[i]->setFrame(false);// 移除输入框的边框

        m_LineEdit[i]->setMaxLength(3);// 每段IP地址最多允许输入 3 个字符

        m_LineEdit[i]->setAlignment(Qt::AlignCenter);//文本居中显示

        m_LineEdit[i]->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Preferred);// 设置控件的尺寸策略，确保控件在布局中合理伸缩

        m_LineEdit[i]->setValidator(new QRegExpValidator(regExp,this));// 设置输入验证器，确保输入内容符合正则表达式的规则

        m_LineEdit[i]->installEventFilter(this); // 安装事件过滤器，用于拦截和处理按键事件（例如焦点切换、删除等逻辑）

        layout->addWidget(m_LineEdit[i]);// 将每个输入框添加到水平布局中


        if (i < 3) {
            labelDot[i] = new QLabel(this);
            labelDot[i]->setText("."); // 设置分隔符文本

            // 调整字体大小
            QFont font = labelDot[i]->font();
            font.setPointSize(10); // 使用点大小设置字体
            labelDot[i]->setFont(font);

            // 调整 QLabel 宽度
            labelDot[i]->setFixedWidth(14); // 增加固定宽度以适配字体大小
            labelDot[i]->setAlignment(Qt::AlignCenter); // 居中对齐文本

            // 添加到布局
            layout->addWidget(labelDot[i]);

        }
        this->setReadOnly(true);
        m_LineEdit[0]->setFocus();
        m_LineEdit[0]->selectAll();
    }

}

bool IPLineEdit::eventFilter(QObject *obj,QEvent *event)
{
    // 检查事件是否发生在当前控件的子控件上，并且事件类型是否为按键事件
    if(children().contains(obj)&&QEvent::KeyPress==event->type()){
        //将事件转换为键盘事件
        QKeyEvent *keyEvent=dynamic_cast<QKeyEvent*>(event);

        //将事件目标对象转换为QLineEdit
        QLineEdit *pCurrentEdit=qobject_cast<QLineEdit*>(obj);

        //判断按下的键
        switch(keyEvent->key())
        {
        case Qt::Key_0:
        case Qt::Key_1:
        case Qt::Key_2:
        case Qt::Key_3:
        case Qt::Key_4:
        case Qt::Key_5:
        case Qt::Key_6:
        case Qt::Key_7:
        case Qt::Key_8:
        case Qt::Key_9:
        {
            // 获取当前输入框的内容
            QString strText=pCurrentEdit->text();

            if(strText.length()<=3&&strText.toInt()*10>255)
            {
                int index=getIndex(pCurrentEdit);

                if(index!=3)
                {
                    m_LineEdit[index+1]->setFocus();
                }
            }
            return QLineEdit::eventFilter(obj,event);
        }
            break;
        case Qt::Key_Left:
        {
            //检查光标是否位于当前输入框的开头位置
            if(!pCurrentEdit->cursorPosition())//获取当前输入框中的光标位置,返回的是光标在文本中的位置索引，起始位置为 0
            {
                // 检查光标是否位于当前输入框的开头位置
                int index=getIndex(pCurrentEdit);

                //如果当前输入框不是第一个
                if(index!=0)
                {
                    //将焦点切换到前一个输入框
                    m_LineEdit[index-1]->setFocus();

                    //将光标移动到上一段的末尾
                    int length=m_LineEdit[index-1]->text().length();
                    m_LineEdit[index-1]->setCursorPosition(length?length:0);

                }
            }
            // 将事件继续传递给默认的事件处理函数
            return QLineEdit::eventFilter(obj, event);
        }
            break;
        case Qt::Key_Right:
        {
            // 检查光标是否位于当前输入框的末尾位置
            if (pCurrentEdit->cursorPosition() == pCurrentEdit->text().length())
            {
                // 获取当前输入框在 m_lineEdit 数组中的索引
                int index = getIndex(pCurrentEdit);

                if(index!=3)
                {
                    m_LineEdit[index+1]->setFocus();
                    // 将光标移动到下一段的开头
                    m_LineEdit[index+1]->setCursorPosition(0);
                }
            }
            // 将事件继续传递给默认的事件处理函数
            return QLineEdit::eventFilter(obj, event);
        }
            break;
        case Qt::Key_Backspace:
        {
            QString strText=pCurrentEdit->text();// 获取当前输入框的内容

            if(strText.isEmpty()){
                int index=getIndex(pCurrentEdit);
                if(index!=0)
                {
                    m_LineEdit[index-1]->setFocus();

                    int length=m_LineEdit[index-1]->text().length();
                    m_LineEdit[index-1]->setCursorPosition(length?length:0);
                }
            }
            // 将事件继续传递给默认的事件处理函数
                return QLineEdit::eventFilter(obj, event);

        }
            break;
        }

    }

}

QString IPLineEdit::text()
{
    //获取IP地址
    //192.168.1.1
    QString ip;
    for (int i=0;i<LINEEDIT_SIZE;i++) {
        ip.append(m_LineEdit[i]->text());
        if (3!=i) {
            ip.append(".");
        }
    }
    return ip;
}

int IPLineEdit::getIndex(QLineEdit *pLineEdit)
{
    int index;
    for (int i=0;i<LINEEDIT_SIZE;i++) {
        if (pLineEdit == m_LineEdit[i]) {
            index = i;
        }
    }
    return index;
}
